package rmi.drs.client.command;

import java.io.IOException;
import java.net.InetAddress;
import java.net.SocketException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Scanner;

import rmi.drs.common.interfaces.RemoteServer;
import rmi.drs.util.MyDatagramSocket;

public class Client {

     Client() {}
    
     static String getCustomerId(){
    	Scanner kb = new Scanner(System.in);
    	System.out.print("Please enter your Customer ID to continue: ");
    	String id = kb.nextLine();
    	while (!checkID(id)){
    		getCustomerId();
    	}
    	System.out.println();
    	
    	return id;
    }
    
     public static String getServerString(String id){
    	char c = id.charAt(0);
    	String $return = null;
    	
    	switch(c){
    		case 'm':
    		case 'M': $return = "Montreal";
    			break;
    		
    		case 't':
    		case 'T': $return = "Toronto";
    			break;
    		
    		case 'v':
    		case 'V': $return = "Vancouver";
    			break;
    	}
    	
    	return $return;
    }
    
     static boolean checkID(String id){
    	if (id.charAt(0) != 'm' || id.charAt(0) != 'M' ||
    			id.charAt(0) != 't' || id.charAt(0) != 'T' ||
    			id.charAt(0) != 'v' || id.charAt(0) != 'V'){
    		return true;
    	}
    	return false;
    }
    
     static void startTransactions(RemoteServer server, String id, Registry registry){
    	try {
			showMenu(server.getServerName());
		} catch (RemoteException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
    	Scanner kb = new Scanner(System.in);
    	int choice = 0;
    	try{
    		choice = kb.nextInt();
    		System.out.println();
    	}
    	catch (Exception e){
    		e.printStackTrace();
    		startTransactions(server, id, registry);
    	}
    	switch (choice){
    		case 0: startTransactions(server, id, registry);
    			break;
    		case 1: buy(server, id, registry);
    			break;
    		case 2: returnItems(server, id, registry);
    			break;
    		case 3: checkStock(server, id, registry);
    			break;
    		case 4: flushToFile(server, id, registry);
				break;
    		case 5: System.exit(0);
				break;
    		default: startTransactions(server, id, registry);
    	}
    }
    
     static void showMenu(String server){
    	System.out.println("***** Store of: " + server + "! *****");
    	System.out.println("********** MAIN MENU **********\n");
    	System.out.println("1. Buy item(s) by Id.\n");
    	System.out.println("2. Return item(s) by Id.\n");
    	System.out.println("3. Check Stock in Stores.\n");
    	System.out.println("4. Back-up data to files.\n");
    	System.out.println("5. Exit.\n");
    	System.out.print("   Choice: ");
    }
    
     static void buy(RemoteServer server, String id, Registry registry){
    	Scanner kb = new Scanner(System.in);
    	System.out.print("Please enter the item id you wish to buy: ");
    	String itemId = kb.next().toUpperCase();
    	System.out.print("Please enter the number of items you wish to buy: ");
    	int itemNumber = 0;
    	try{
    		itemNumber = kb.nextInt();
    	}
    	catch (Exception e){
    		e.printStackTrace();
    		startTransactions(server, id, registry);
    	}
    	boolean bought = false;
    	if (itemNumber > 0){
    		try {
    			bought = server.buy(id, itemId, itemNumber);
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
    	if (!bought){
    		System.out.println("Item(s) could not be bought!");
    		preStartTransactions(server, id, registry);
    	}
    	else{
    		System.out.println("Item(s) successfully bought!");
    		preStartTransactions(server, id, registry);
    	}
    }
    
     static void flushToFile(RemoteServer server, String id, Registry registry){
    
		String[] serversString = null;
		try {
			serversString = registry.list();
			for (String s : serversString){
				RemoteServer serverS = (RemoteServer) registry.lookup(s);
				serverS.flushToFile();
			}
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		preStartTransactions(server, id, registry);
		
    }
    
     static void returnItems(RemoteServer server, String id, Registry registry){
    	Scanner kb = new Scanner(System.in);
    	System.out.print("Please enter the item id you wish to return: ");
    	String itemId = kb.next().toUpperCase();
    	System.out.print("Please enter the number of items you wish to return: ");
    	int itemNumber = 0;
    	try{
    		itemNumber = kb.nextInt();
    	}
    	catch (Exception e){
    		e.printStackTrace();
    		preStartTransactions(server, id, registry);
    	}
    	boolean check = false;
    	if (itemNumber > 0){
    		try {
    			check = server.returnItems(id, itemId, itemNumber);
    			System.out.println("Item(s) successfully returned!");
    			preStartTransactions(server, id, registry);
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
    	else if (!check){
    		System.out.println("Item(s) could not be returned!");
    		preStartTransactions(server, id, registry);
    	}
    }
    
     static void checkStock(RemoteServer server, String customerId, Registry registry){
    	Scanner kb = new Scanner(System.in);
    	System.out.print("Please enter the item id you wish to check the stock: ");
    	String itemId = kb.next().toUpperCase();
    	try {
    		System.out.print("\nStock information for the iteam " + itemId + ":");
    		
    		MyDatagramSocket clientSocket = null;
			try {
				clientSocket = new MyDatagramSocket(1994);
			} catch (SocketException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
    		
    		if (clientSocket != null){
    			if (server.getServerName().equalsIgnoreCase("Montreal")){
        			try {
        				clientSocket.sendMessage(InetAddress.getLocalHost(), 9001, "checkStock-" + itemId);
        				clientSocket.sendMessage(InetAddress.getLocalHost(), 9002, "checkStock-" + itemId);
        				clientSocket.sendMessage(InetAddress.getLocalHost(), 9003, "checkStock-" + itemId);
        			} catch (IOException e) {
        				// TODO Auto-generated catch block
        				e.printStackTrace();
        			}
        		}
        		else if (server.getServerName().equalsIgnoreCase("Toronto")){
        			try {
        				clientSocket.sendMessage(InetAddress.getLocalHost(), 9002, "checkStock-" + itemId);
        				clientSocket.sendMessage(InetAddress.getLocalHost(), 9001, "checkStock-" + itemId);
        				clientSocket.sendMessage(InetAddress.getLocalHost(), 9003, "checkStock-" + itemId);
        			} catch (IOException e) {
        				// TODO Auto-generated catch block
        				e.printStackTrace();
        			}
        		}
        		else if (server.getServerName().equalsIgnoreCase("Vancouver")){
        			try {
        				clientSocket.sendMessage(InetAddress.getLocalHost(), 9003, "checkStock-" + itemId);
        				clientSocket.sendMessage(InetAddress.getLocalHost(), 9001, "checkStock-" + itemId);
        				clientSocket.sendMessage(InetAddress.getLocalHost(), 9002, "checkStock-" + itemId);
        			} catch (IOException e) {
        				// TODO Auto-generated catch block
        				e.printStackTrace();
        			}
        		}
    		}
    		else{
    			throw new Exception();
    		}
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			try {
				System.out.println("\nCould not find stock information for " + server.getServerName() + ".");
			} catch (RemoteException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
				System.out.println("FATAL ERROR\n");
			}
		}
    	preStartTransactions(server, itemId, registry);
    }
    
     static void preStartTransactions(RemoteServer server, String id, Registry registry){
    	System.out.print("\nType 0 to return the main menu: ");
    	Scanner sc = new Scanner(System.in);
    	int n = 0;
    	try{
    		n = sc.nextInt();
    	}
    	catch (Exception e){
    		e.printStackTrace();
    		preStartTransactions(server, id, registry);
    	}
    	if (n == 0){
    		startTransactions(server, id, registry);
    	}
    	else{
    		preStartTransactions(server, id, registry);
    	}
    	
    }
    
     static void introMessage(){
    	System.out.println("/************************************************\\");
    	System.out.println(" ***************Welcome to the DRS!**************");
    	System.out.println(" ************************************************");
    	System.out.println(" ***********Owner: Austin Takam Nzokam***********");
    	System.out.println(" ******************ID: 9465413*******************");
    	System.out.println("\\************************************************/");
    	System.out.println();
    }

    public static void main(String[] args) {
    	
    	try {
    		introMessage();
    		String customerId = getCustomerId();
    		Registry registry = LocateRegistry.getRegistry(1099);
    		RemoteServer stub = (RemoteServer) registry.lookup(getServerString(customerId)); 
    		startTransactions(stub, customerId, registry);
    	} 
    	catch (Exception e) {
    		System.err.println("Client exception: " + e.toString());
    		e.printStackTrace();
    	}
    }
}
